package com.redepronik.negosysfab.invfac.controller;

import static com.redepronik.negosys.utils.Utils.compareTo;
import static com.redepronik.negosys.utils.Utils.moraTotal;
import static com.redepronik.negosys.utils.Utils.multiplicarDivide;
import static com.redepronik.negosys.utils.Utils.newBigDecimal;
import static com.redepronik.negosys.utils.Utils.redondearTotales;
import static com.redepronik.negosys.utils.Utils.timestamp;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.redepronik.negosys.invfac.entity.Banco;
import com.redepronik.negosys.invfac.entity.Credito;
import com.redepronik.negosys.invfac.entity.Detallecredito;
import com.redepronik.negosys.invfac.entity.Egreso;
import com.redepronik.negosys.invfac.entity.Entrada;
import com.redepronik.negosys.invfac.entity.Garante;
import com.redepronik.negosys.invfac.entity.Pagocredito;
import com.redepronik.negosys.invfac.entity.Pagoentrada;
import com.redepronik.negosys.invfac.entity.Tipopago;
import com.redepronik.negosys.invfac.entityAux.CantidadesCreditoReporte;
import com.redepronik.negosys.invfac.entityAux.CantidadesEntradaReporte;
import com.redepronik.negosys.invfac.entityAux.NumeroCuotasReporte;
import com.redepronik.negosys.invfac.service.BancoService;
import com.redepronik.negosys.invfac.service.EgresoService;
import com.redepronik.negosys.invfac.service.LocalService;
import com.redepronik.negosys.invfac.service.MoraService;
import com.redepronik.negosys.invfac.service.ProductoService;
import com.redepronik.negosys.invfac.service.TipoPagoService;
import com.redepronik.negosys.rrhh.entity.Persona;
import com.redepronik.negosys.rrhh.service.ClienteService;
import com.redepronik.negosys.rrhh.service.PersonaService;

@Controller
@Scope("session")
public class CobroCreditoBean implements Serializable {
	private static final long serialVersionUID = 1L;

	@Autowired
	private PersonaService personaService;

	@Autowired
	private EgresoService egresoService;

	@Autowired
	private ProductoService productoService;

	@Autowired
	private ClienteService clienteService;

	@Autowired
	private LocalService localService;

	@Autowired
	private TipoPagoService tipoPagoService;

	@Autowired
	private BancoService bancoService;

	@Autowired
	private MoraService moraService;

	private List<Egreso> listaEgresos;
	private List<Tipopago> listTiposPago;

	private Egreso egreso;
	private Persona cliente;
	private Persona garante;
	private List<Persona> garantes;
	private List<Persona> listaGarantes;
	private Entrada entrada;
	private Pagoentrada pagosEntrada;
	private Tipopago tiposPago;
	private Banco banco;
	private Credito credito;
	private Detallecredito detallesCredito;
	private Pagocredito pagosCredito;

	private Date fechaPagoEntrada;
	private CantidadesEntradaReporte cantidadesEntradaReporte;

	private Date fechaPagoCredito;
	private CantidadesCreditoReporte cantidadesCreditoReporte;

	private String nombreCliente;

	private Date fechaActual;

	private NumeroCuotasReporte numeroCuotas;

	private boolean bnCredito = true;
	private boolean bnEntrada = true;

	private boolean bnBanco;
	private boolean bnEfectivo;
	private boolean bnTarjeta;

	private String chequeTarjetaVaucher;
	private String chequeTarjetaCuenta;

	private List<Persona> listaClienteBusqueda;
	private String criterioClienteBusqueda;

	public CobroCreditoBean() {
		listaGarantes = new ArrayList<Persona>();
		listaEgresos = new ArrayList<Egreso>();
		listTiposPago = new ArrayList<Tipopago>();

		egreso = new Egreso();
		cliente = new Persona();
		garante = new Persona();
		entrada = new Entrada();
		pagosEntrada = new Pagoentrada();
		tiposPago = new Tipopago();
		banco = new Banco();
		credito = new Credito();
		detallesCredito = new Detallecredito();
		pagosCredito = new Pagocredito();

		fechaPagoEntrada = new Date();
		cantidadesEntradaReporte = new CantidadesEntradaReporte();

		fechaPagoCredito = new Date();
		cantidadesCreditoReporte = new CantidadesCreditoReporte();

		fechaActual = new Date();

		bnBanco = false;
		bnEfectivo = false;
		bnTarjeta = false;

		tiposPago.setTipopagoid(1);
	}

	public void activarBotonCredito() {
		bnCredito = true;
	}

	public void activarBotonEntrada() {
		bnEntrada = true;
	}

	public void actualizar(ActionEvent actionEvent) {
		egresoService.actualizar(egreso, null);
		presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_INFO,
				"ACTUALIZO", "Egreso: " + egreso.getCodigodocumento()));
	}

	public void calcularCuota() {
		if (detallesCredito.getDetallecreditoid() != null) {
			cantidadesCreditoReporte = egresoService.calcularCuota(
					detallesCredito, cantidadesCreditoReporte,
					egreso.getFechainicio(), fechaPagoCredito);
			bnCredito = false;
		}
	}

	public void calcularEntrada() {
		if (entrada.getEntradaid() != null) {
			cantidadesEntradaReporte = egresoService.calcularEntrada(entrada,
					cantidadesEntradaReporte, egreso.getFechainicio(),
					fechaPagoEntrada);
			bnEntrada = false;
		}
	}

	public void calcularNumeroCuotasEntradasCreditos() {
		if (numeroCuotas == null) {
			numeroCuotas = new NumeroCuotasReporte();
			numeroCuotas = egresoService.calcularNumeroCuotasEntradasCreditos(
					egreso, numeroCuotas, fechaActual);
		}
	}

	public void cancelarCredito() {
		credito = new Credito();
		pagosCredito = new Pagocredito();
		tiposPago = new Tipopago();
		banco = new Banco();
	}

	public void cancelarDetalleCredito() {
		cantidadesCreditoReporte = new CantidadesCreditoReporte();
		fechaPagoCredito = new Date();
		detallesCredito = new Detallecredito();
	}

	public void cancelarDetalleEntrada() {
		cantidadesEntradaReporte = new CantidadesEntradaReporte();
		fechaPagoEntrada = new Date();
		entrada = new Entrada();
	}

	public void cancelarEntrada() {
		entrada = new Entrada();
		pagosEntrada = new Pagoentrada();
		tiposPago = new Tipopago();
		banco = new Banco();
	}

	public void eliminarGarante() {
		// Garante g = new Garante();
		garante = personaService.obtenerPorPersonaId(garante.getPersonaid());
		// g.setCedula(garante.getCedula());
		List<Garante> gara = egreso.getCredito().getGarantes();
		for (int i = 0; i < gara.size(); i++) {
			// if (gara.get(i).getCedula().compareTo(g.getCedula()) == 0) {
			// gara.remove(i);
			// presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_INFO,
			// "ELIMINO", "EL GARANTE SE ELIMINO CON EXITO"));
			// break;
			// }
		}
		egreso.getCredito().setGarantes(gara);
	}

	public Banco getBanco() {
		return banco;
	}

	public CantidadesCreditoReporte getCantidadesCreditoReporte() {
		return cantidadesCreditoReporte;
	}

	public CantidadesEntradaReporte getCantidadesEntradaReporte() {
		return cantidadesEntradaReporte;
	}

	public String getChequeTarjetaCuenta() {
		return chequeTarjetaCuenta;
	}

	public String getChequeTarjetaVaucher() {
		return chequeTarjetaVaucher;
	}

	public Persona getCliente() {
		return cliente;
	}

	public Credito getCredito() {
		return credito;
	}

	public String getCriterioClienteBusqueda() {
		return criterioClienteBusqueda;
	}

	public Detallecredito getDetallesCredito() {
		if (detallesCredito.getPagocreditos() == null)
			detallesCredito.setPagocreditos(new ArrayList<Pagocredito>());

		return detallesCredito;
	}

	public Egreso getEgreso() {
		return egreso;
	}

	public Entrada getEntrada() {
		if (entrada.getPagoentradas() == null)
			entrada.setPagoentradas(new ArrayList<Pagoentrada>());

		return entrada;
	}

	public Date getFechaActual() {
		return fechaActual;
	}

	public Date getFechaPagoCredito() {
		return fechaPagoCredito;
	}

	public Date getFechaPagoEntrada() {
		return fechaPagoEntrada;
	}

	public Persona getGarante() {
		return garante;
	}

	public List<Persona> getGarantes() {
		if (egreso.getEgresoid() != null)
			if (egreso.getCredito() != null
					&& egreso.getCredito().getGarantes() != null)
				garantes = clienteService.obtenerGarante(egreso.getCredito()
						.getGarantes());

		return garantes;
	}

	public List<Persona> getListaClienteBusqueda() {
		return listaClienteBusqueda;
	}

	public List<Egreso> getListaEgresos() {
		return listaEgresos;
	}

	public List<Persona> getListaGarantes() {
		return listaGarantes;
	}

	public List<Tipopago> getListTiposPago() {
		listTiposPago = tipoPagoService.obtener();
		return listTiposPago;
	}

	public String getNombreCliente() {
		return nombreCliente;
	}

	public NumeroCuotasReporte getNumeroCuotas() {
		return numeroCuotas;
	}

	public Pagocredito getPagosCredito() {
		return pagosCredito;
	}

	public Pagoentrada getPagosEntrada() {
		return pagosEntrada;
	}

	public Tipopago getTiposPago() {
		return tiposPago;
	}

	public void insertarGarante() {
		if (garante.getPersonaid() != null) {
			Garante g = new Garante();
			garante = personaService
					.obtenerPorPersonaId(garante.getPersonaid());
			// g.setCedula(garante.getCedula());
			boolean bn = true;
			// List<Garante> gara = egreso.getCredito().getGarantes();
			// for (Garante garante : gara)
			// if (garante.getCedula().compareTo(g.getCedula()) == 0) {
			// bn = false;
			// presentaMensaje(new FacesMessage(
			// FacesMessage.SEVERITY_ERROR, "ERROR",
			// "EL GARANTE YA EXISTE"));
			// break;
			// }
			if (bn) {
				egreso.getCredito().addGarante(g);
				presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_INFO,
						"INSERTO", "EL GARANTE SE INSERTO CON EXITO"));
			}
		}
	}

	public boolean isBnBanco() {
		return bnBanco;
	}

	public boolean isBnCredito() {
		return bnCredito;
	}

	public boolean isBnEfectivo() {
		return bnEfectivo;
	}

	public boolean isBnEntrada() {
		return bnEntrada;
	}

	public boolean isBnTarjeta() {
		return bnTarjeta;
	}

	public void limpiarObjetosBusquedaCliente() {
		criterioClienteBusqueda = new String();
		listaClienteBusqueda = new ArrayList<Persona>();
	}

	public void obtenerCliente() {
		if (!cliente.getCedula().equals("")
				&& !cliente.getCedula().equals(null))
			cliente = clienteService.obtenerPorCedula(cliente.getCedula());
		if (cliente == null) {
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"ERROR", "EL CLIENTE NO EXISTE"));
			cliente = new Persona();
		} else
			listaEgresos = egresoService.obtenerPorEstado(cliente.getCedula(),
					1, null, null, null);
	}

	public void obtenerClientes() {
		if (!nombreCliente.equals(null))
			listaGarantes = clienteService.obtenerGarante(nombreCliente);
	}

	public void obtenerClientesPorBusqueda() {
		if (criterioClienteBusqueda.length() >= 0
				&& criterioClienteBusqueda.length() <= 3) {
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"MENSAJE DEL SISTEMA", "INGRESE MAS DE 3 CARACTERES"));
		} else {
			listaClienteBusqueda = clienteService
					.obtener(criterioClienteBusqueda.toUpperCase());
			if (listaClienteBusqueda.isEmpty()) {
				presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_WARN,
						"MENSAJE DEL SISTEMA",
						"NO SE ENCONTRO NINGUNA COINCIDENCIA"));
			}
			criterioClienteBusqueda = new String();
		}
	}

	public void pagarCredito() {
		BigDecimal t = redondearTotales(cantidadesCreditoReporte
				.getTotalCredito());
		BigDecimal c = redondearTotales(pagosCredito.getCuota());

		if (c.compareTo(t) > 0 || c.compareTo(newBigDecimal()) <= 0)
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"MENSAJE DEL SISTEMA",
					"INGRESE UN VALOR VALIDO PARA LA CUOTA"));
		else {
			tiposPago = new Tipopago();
			bnBanco = false;
			bnEfectivo = false;
			bnTarjeta = false;
			tiposPago.setTipopagoid(1);

			if (detallesCredito.getDetallecreditoid() != null)
				if (compareTo(fechaPagoCredito, detallesCredito.getFechamora()) >= 0) {
					BigDecimal mora = moraService.obtenerPorFecha(
							egreso.getFechainicio()).getPorcentaje();
					BigDecimal moraTotal = moraTotal(fechaPagoCredito,
							detallesCredito.getFechamora(), mora);
					detallesCredito.setMora(multiplicarDivide(moraTotal,
							detallesCredito.getSaldo()));
					detallesCredito.setSaldo(detallesCredito.getSaldo().add(
							detallesCredito.getMora()));
				} else {
					detallesCredito.setMora(newBigDecimal());
					detallesCredito.setSaldo(detallesCredito.getSaldo().add(
							detallesCredito.getMora()));
				}

			pagosCredito.setTipopago(tipoPagoService
					.obtenerPorTipoPagoId(tiposPago.getTipopagoid()));

			if (banco.getBancoid() != null && banco.getBancoid() != 0)
				pagosCredito.setBanco(bancoService.obtenerPorBancoId(
						banco.getBancoid()).getNombre());

			if (pagosCredito.getTipopago().getTipopagoid() == 3) {
				pagosCredito.setFechapago(timestamp("01-01-1900"));
				pagosCredito.setPagado(false);
			} else {
				pagosCredito.setFechapago(timestamp(fechaPagoCredito));
				pagosCredito.setPagado(true);
			}

			boolean bn = true;
			for (Pagocredito pc : detallesCredito.getPagocreditos())
				if (pc.getPagado() == false)
					bn = false;

			if (t.compareTo(c) == 0 && bn) {
				detallesCredito.setPagado(true);
				detallesCredito.setSaldo(new BigDecimal("0"));
				detallesCredito.setFechapago(fechaPagoCredito);
			} else {
				detallesCredito.setFechamora(fechaPagoCredito);
				detallesCredito.setSaldo(detallesCredito.getSaldo().subtract(
						pagosCredito.getCuota()));
			}
			calcularCuota();
			detallesCredito.addPagocredito(pagosCredito);
			pagosCredito = new Pagocredito();
			tiposPago = new Tipopago();
		}
	}

	public void pagarEntrada() {
		tiposPago = new Tipopago();
		bnBanco = false;
		bnEfectivo = false;
		bnTarjeta = false;
		tiposPago.setTipopagoid(1);
		if (entrada.getEntradaid() != null) {
			if (compareTo(fechaPagoEntrada, entrada.getFechamora()) >= 0) {
				BigDecimal mora = moraService.obtenerPorFecha(
						egreso.getFechainicio()).getPorcentaje();
				BigDecimal moraTotal = moraTotal(fechaPagoEntrada,
						entrada.getFechamora(), mora);
				entrada.setMora(multiplicarDivide(moraTotal, entrada.getSaldo()));
				entrada.setSaldo(entrada.getSaldo().add(entrada.getMora()));
			} else {
				entrada.setMora(newBigDecimal());
				entrada.setSaldo(entrada.getSaldo().add(entrada.getMora()));
			}
		}

		pagosEntrada.setTipopago(tipoPagoService.obtenerPorTipoPagoId(tiposPago
				.getTipopagoid()));

		if (banco.getBancoid() != 0)
			pagosEntrada.setBanco(bancoService.obtenerPorBancoId(
					banco.getBancoid()).getNombre());

		if (pagosEntrada.getTipopago().getTipopagoid() == 3) {
			pagosEntrada.setFechapago(timestamp("01-01-1900"));
			pagosEntrada.setPagado(false);
		} else {
			pagosEntrada.setFechapago(timestamp(fechaPagoEntrada));
			pagosEntrada.setPagado(true);
		}

		BigDecimal s = redondearTotales(entrada.getSaldo());
		BigDecimal c = redondearTotales(pagosEntrada.getCuota());

		boolean bn = true;
		for (Pagoentrada iterable : entrada.getPagoentradas())
			if (iterable.getPagado() == false)
				bn = false;

		if (s.compareTo(c) == 0 && bn) {
			entrada.setPagado(true);
			entrada.setSaldo(new BigDecimal("0"));
			entrada.setFechapago(fechaPagoEntrada);
		} else {
			entrada.setFechamora(fechaPagoEntrada);
			entrada.setSaldo(entrada.getSaldo().subtract(
					pagosEntrada.getCuota()));
		}
		calcularEntrada();
		entrada.addPagoentrada(pagosEntrada);
		pagosEntrada = new Pagoentrada();
		tiposPago = new Tipopago();
	}

	private void presentaMensaje(FacesMessage message) {
		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public void setBanco(Banco banco) {
		this.banco = banco;
	}

	public void setBnBanco(boolean bnBanco) {
		this.bnBanco = bnBanco;
	}

	public void setBnCredito(boolean bnCredito) {
		this.bnCredito = bnCredito;
	}

	public void setBnEfectivo(boolean bnEfectivo) {
		this.bnEfectivo = bnEfectivo;
	}

	public void setBnEntrada(boolean bnEntrada) {
		this.bnEntrada = bnEntrada;
	}

	public void setBnTarjeta(boolean bnTarjeta) {
		this.bnTarjeta = bnTarjeta;
	}

	public void setCantidadesCreditoReporte(
			CantidadesCreditoReporte cantidadesCreditoReporte) {
		this.cantidadesCreditoReporte = cantidadesCreditoReporte;
	}

	public void setCantidadesEntradaReporte(
			CantidadesEntradaReporte cantidadesEntradaReporte) {
		this.cantidadesEntradaReporte = cantidadesEntradaReporte;
	}

	public void setChequeTarjetaCuenta(String chequeTarjetaCuenta) {
		this.chequeTarjetaCuenta = chequeTarjetaCuenta;
	}

	public void setChequeTarjetaVaucher(String chequeTarjetaVaucher) {
		this.chequeTarjetaVaucher = chequeTarjetaVaucher;
	}

	public void setCliente(Persona cliente) {
		this.cliente = cliente;
	}

	public void setCredito(Credito credito) {
		this.credito = credito;
	}

	public void setCriterioClienteBusqueda(String criterioClienteBusqueda) {
		this.criterioClienteBusqueda = criterioClienteBusqueda;
	}

	public void setDetallesCredito(Detallecredito detallesCredito) {
		this.detallesCredito = detallesCredito;
	}

	public void setEgreso(Egreso egreso) {
		this.egreso = egreso;
	}

	public void setEntrada(Entrada entrada) {
		this.entrada = entrada;
	}

	public void setFechaActual(Date fechaActual) {
		this.fechaActual = fechaActual;
	}

	public void setFechaPagoCredito(Date fechaPagoCredito) {
		this.fechaPagoCredito = fechaPagoCredito;
	}

	public void setFechaPagoEntrada(Date fechaPagoEntrada) {
		this.fechaPagoEntrada = fechaPagoEntrada;
	}

	public void setGarante(Persona garante) {
		this.garante = garante;
	}

	public void setGarantes(List<Persona> garantes) {
		this.garantes = garantes;
	}

	public void setListaClienteBusqueda(List<Persona> listaClienteBusqueda) {
		this.listaClienteBusqueda = listaClienteBusqueda;
	}

	public void setListaEgresos(List<Egreso> listaEgresos) {
		this.listaEgresos = listaEgresos;
	}

	public void setListaGarantes(List<Persona> listaGarantes) {
		this.listaGarantes = listaGarantes;
	}

	public void setListTiposPago(List<Tipopago> listTiposPago) {
		this.listTiposPago = listTiposPago;
	}

	public void setNombreCliente(String nombreCliente) {
		this.nombreCliente = nombreCliente;
	}

	public void setNumeroCuotas(NumeroCuotasReporte numeroCuotas) {
		this.numeroCuotas = numeroCuotas;
	}

	public void setPagosCredito(Pagocredito pagosCredito) {
		this.pagosCredito = pagosCredito;
	}

	public void setPagosEntrada(Pagoentrada pagosEntrada) {
		this.pagosEntrada = pagosEntrada;
	}

	public void setTiposPago(Tipopago tiposPago) {
		this.tiposPago = tiposPago;
	}

	public void tipoPago() {
		if (tiposPago.getTipopagoid() == 1) {
			setBnEfectivo(true);
			setBnTarjeta(false);
			setBnBanco(false);
		} else if (tiposPago.getTipopagoid() == 2) {
			setBnEfectivo(false);
			setBnTarjeta(true);
			setBnBanco(false);
			setChequeTarjetaCuenta("# TARJETA");
			setChequeTarjetaVaucher("# VAUCHER");
		} else if (tiposPago.getTipopagoid() == 3) {
			setBnEfectivo(false);
			setBnTarjeta(true);
			setBnBanco(true);
			setChequeTarjetaCuenta("# CUENTA");
			setChequeTarjetaVaucher("# CHEQUE");
		}
	}

}